package com.android.newsreader;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView;

/**
* The initial activity class launched on application start-up
* 
* This activity displays a list of available news channels
*/
public class NewsHome extends Activity implements OnItemClickListener {
	
	private RSSChannelProvider mDb4oHelper = null;
	
	private String channelsAsStr[] = null;
	private String[] channelNames = null;
	private List<RSSChannel> channels = null;

	/**
	 *  Called when the activity is first created. 
	 * */
	public void onCreate(Bundle savedInstanceState) 
    {
		super.onCreate(savedInstanceState);
        setContentView(R.layout.home);
        
        dbHelper();
        initialiseChannels();
        
    }
	
	/**
	 *  Populates activity with a list of news channels
	 *  
	 * */
	private void initialiseChannels() {
		createRSSChannels();
        
        ListView newslist = (ListView) findViewById(R.id.newslist);
        
        newslist.setAdapter(new IconAdapter());
        
        //Sets listener for list item clicks
        newslist.setOnItemClickListener(this);
        
        //Adds context menu for list items
        this.registerForContextMenu(newslist);

	}
	
	/**
	 *  Creates an Options menu for the activity
	 *  
	 *  Menu Options:
	 *  Add  - Opens activity to input RSS Channel
	 *  Cancel - does nothing
	 *  
	 * */
	public boolean onCreateOptionsMenu(Menu menu) 
    {
    	super.onCreateOptionsMenu(menu);
    	
    	menu.add(0,0,0,getString(R.string.add_channel));
    	menu.add(0,1,1,getString(R.string.cancel));
    	
    	return true;
    }
    
	/**
	 *  Sets behaviour for the menu options
	 *  
	 * */
    public boolean onOptionsItemSelected(MenuItem item){
        switch (item.getItemId()) {
        case 0:
        	// On 'Add' open InputChannel activity
        	Intent intent = new Intent(NewsHome.this, 
    				InputChannel.class);
        	startActivity(intent);
        	return true;
        case 1:
        	// On 'Cancel' do nothing
        	return true;
    	}
        return false;
    }

    /**
	 *  Sets behaviour for the list item clicks
	 *  
	 * */
	@Override
	public void onItemClick(AdapterView<?> parent, View item, int position, long id) {
		// Open TabWidget Activity for selected news channel
		Intent intent = new Intent(NewsHome.this, 
				TabWidget.class);
		
		String selectedChannel = channelNames[position];
		
		// Retrieves RSSChannel objects from db by channel name  
    	List categories = this.mDb4oHelper.findByName(selectedChannel);
    	Iterator categIter = categories.iterator();
    	
    	while (categIter.hasNext()) {
    		RSSChannel aChannel = (RSSChannel)categIter.next();
    		intent.putExtra(aChannel.getCategory(), aChannel);
    	}
    	
    	startActivity(intent);
		
	}
	
	/**
	 *  Creates News Channels for list
	 *  
	 *  Channels will be retrieved from resource file on first use
	 *  of the application and store default channels in the database.
	 *  Subsequent calls to this method will retrieve channels from 
	 *  database.
	 *  
	 * */
	private void createRSSChannels(){
		
		channels = this.mDb4oHelper.findAll();
		
		if (channels.isEmpty()) {
			createRSSChannelsFromRes();
		} 
		
		populateChannelsNames();
	}
	
	/**
	 *  Creates News Channels from String Array in resource file.
	 *  
	 * */
	private void createRSSChannelsFromRes(){
		channelsAsStr = this.getResources().getStringArray(R.array.channels);
		channels = new ArrayList<RSSChannel>();
		
		if (channelsAsStr!=null){
			
			for (int i=0; i< channelsAsStr.length; i++){
				RSSChannel newChannel = RSSChannel.getChannel(channelsAsStr[i]);
				channels.add(newChannel);
				mDb4oHelper.store(newChannel);
			}
			
		}
		
	}
	
	/**
	 *  Creates an array of News Channels names.
	 *  
	 * */
	private void populateChannelsNames(){
		
		ArrayList channelNamesList = new ArrayList<String>();
		Iterator channelIterator = channels.iterator();
		String lastName = "";
		
		while(channelIterator.hasNext()){	
			String name = ((RSSChannel)channelIterator.next()).getName();
			if (!lastName.equalsIgnoreCase(name)) {
				channelNamesList.add(name);
			}
			lastName = name;
		}
		
		Object[] channelNamesObj = channelNamesList.toArray();
        
        channelNames = new String[channelNamesObj.length];
        for (int i=0; i<channelNames.length; i++) {
        	channelNames[i] = (String)channelNamesObj[i]; 
        }
	}
	
	
	/**
     * Create RSSChannelProvider instance
     */
     private RSSChannelProvider dbHelper() {
         if (mDb4oHelper == null) {
            mDb4oHelper = RSSChannelProvider.getInstance(this);
            mDb4oHelper.db();
         }
         
         return mDb4oHelper;
     } 
	
     
     /**
      * Close database before exiting the application
      */
      @Override
      protected void onPause() {
           super.onDestroy();
           if (mDb4oHelper != null)
        	   mDb4oHelper.close();
      }
      
      @Override
  	  protected void onResume() {
  		// TODO Auto-generated method stub
  		super.onResume();
  		dbHelper();
  		initialiseChannels();
  		
  	  }
      
     /**
  	   *  A private IconAdapter class which extends 'android.widget.ArrayAdapter'
  	   *  
  	   *  This class creates rows for the channel list. 
  	   *  Each row contains both an image and text.
  	   *  
  	 * */
     private class IconAdapter extends ArrayAdapter {

    		public IconAdapter() {
    			super(NewsHome.this, R.layout.list_item, channelNames);
    			
    		}
    		
    		public View getView(int position, View convertView, ViewGroup parent) {
    			
    			View row = convertView;
    			
    			if (row==null) {
    				LayoutInflater inflater = getLayoutInflater();
    				row = inflater.inflate(R.layout.list_item, parent, false);
    			}
    			
    			TextView label = (TextView)row.findViewById(R.id.itemlabel);
    			
    			label.setText(channelNames[position]);
    			
    			ImageView icon = (ImageView)row.findViewById(R.id.itemicon);
    			
    			if (channelNames[position].equalsIgnoreCase("RTE")) {
                	icon.setImageResource(R.drawable.rtelogo);
    			} else if (channelNames[position].equalsIgnoreCase("Guardian")) {
                	icon.setImageResource(R.drawable.gulogo);      
    			} else if (channelNames[position].equalsIgnoreCase("BBC")) {
                	icon.setImageResource(R.drawable.bbclogo); 
    			} else {
    				icon.setImageResource(R.drawable.miscnews);
    			}
    			
    			
    			return row;
    		}



    	}
     
     /**
  	  *  Creates Context menu for list items
  	  *  
  	  *  Delete and Cancel are the available context
  	  *  menu options
  	  *  
  	  * */
      @Override
      public void onCreateContextMenu(ContextMenu menu, View v,
          ContextMenuInfo menuInfo) {
        if (v.getId()==R.id.newslist) {
          AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
          menu.setHeaderTitle(channelNames[info.position]);
          
          menu.add(Menu.NONE, 0, 0, getString(R.string.delete));
          menu.add(Menu.NONE, 1, 1, getString(R.string.cancel));
          
        }
      }
      
     /**
  	  *  Adds behaviour to Context menu options
  	  *  
  	  *  'Delete' removes the select channel from the db
  	  *  'Cancel' does nothing
  	  *  
  	  * */
      @Override
      public boolean onContextItemSelected(MenuItem item) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
        int menuItemIndex = item.getItemId();
        
        String listItemName = channelNames[info.position];

        switch (menuItemIndex) {
        	case 0:
        		List itemsToDelete = mDb4oHelper.findByName(listItemName);
        		if (itemsToDelete.size() > 0) {
        			try {
        				mDb4oHelper.delete((RSSChannel)itemsToDelete.get(0));
        			} catch (Exception e) {
						Toast toast = Toast.makeText(getApplicationContext(), getString(R.string.error_del), Toast.LENGTH_LONG);
						toast.show();	
					}
        			this.initialiseChannels();
        		}
        		break;
        	case 1:
        		return true;
        }
        
        return true;
      }

}
